/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package server;

import common.Config;
import common.model.Visitor;
import common.model.message.SetGuideMessage;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author nicolas
 */
public class GuideManagerImpl implements GuideManager, Runnable {

    //Variables declarations
    protected Queue<String> queue = null;
    private VisitorsGroup visitorsGroup = null;
    private long t = System.currentTimeMillis();
    private long TIMETOBEGUIDEINMILLISEC = Long.parseLong(Config.getProperty().getProperty("server.timetobeguideinmillisec"));
    private boolean aGuideActive = false;
    private String currentGuide = "";
    private boolean timeElapsedForce = false;

    public GuideManagerImpl(VisitorsGroup group) {
        this.visitorsGroup = group;
        queue = new ConcurrentLinkedQueue<String>();
    }

    /**
     * Add a visitor to the queue to wait
     * @param visitor
     */
    public void addGuide(String userName) {
/*
        //Already checked in run
        if ((queue.isEmpty() && aGuideActive == false) ||
                (isTimeElapsed(System.currentTimeMillis()) && aGuideActive)) {
                setGuide(userName);
        } else {
            //You must wait lil bit
            queue.add(userName);
        }
 */     //Makes sure one doesn't have more than one turn
        if( !queue.contains(userName) ) queue.add(userName);
    }

    private void setGuide(String userName) {
        setTimeElapsedForce(false);
        aGuideActive = true;
        if( !currentGuide.equals(userName) )
        {
            //Tell old guide that he's not guide
            if(!currentGuide.equals("")){
                visitorsGroup.broadcast(new SetGuideMessage(currentGuide,false).messageToString());
            }
            //Tell new guide that he's guide
            visitorsGroup.broadcast(new SetGuideMessage(userName,true).messageToString());
            System.out.println("NEW GUIDE" + userName);
            currentGuide = userName; //visitor is the new guide
            this.t = System.currentTimeMillis(); //reset counter
        }
    }

    private boolean isTimeElapsed(long time) {
        if ((time - this.t) > TIMETOBEGUIDEINMILLISEC) {
            return true;
        }
        return false;
    }

    private void setTimeElapsedForce(boolean timeElapsed){
        this.timeElapsedForce = timeElapsed;
    }

    /**
     * Can remove from the queue if the visitor don't want anymore to be guide.
     * @param visitor
     */
    public void removeGuide(String userName) {
        if(queue.contains(userName)){
            queue.remove(userName);
        }
        //If the current guide doesn't wanna be guide anymore we tell the others
        if( currentGuide.equals(userName) )
        {
            this.setTimeElapsedForce(true);
            aGuideActive = false;
            visitorsGroup.broadcast(new SetGuideMessage(currentGuide,false).messageToString());
            currentGuide = "";
        }
    }

    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            if ((isTimeElapsed(System.currentTimeMillis())|| timeElapsedForce ==true)
                    && !queue.isEmpty())
            {   //If only one client wants to be guide no changes are needed
                if( queue.size() > 1 )
                {
                    String tmp = queue.poll();
                    addGuide(tmp); //put back the new guide at the end of the queue so that the guide always change
                }
                setGuide(queue.element()); //next in the queue can be guide
            }
            try {
                //Wait a moment
                Thread.sleep(500);
            } catch (InterruptedException ex) {
                Logger.getLogger(GuideManagerImpl.class.getName()).log(Level.SEVERE, null, ex);
            }
  
        }

    }
}
